#include "exception.h"
#include "group.h"
#include "unit.h"
#include "config.h"
#include <iostream>

using std::cerr;
using std::endl;

uint64_t BaseUnit::idCounter;

BaseUnit::BaseUnit(uint32_t index, uint32_t team): index(index), team(team){
    id = idCounter++;
}

double BaseUnit::getLife()const{ return life; }

double BaseUnit::getLifeLimit()const{
    const ArmyInfo *ptr = getArmy(index);
    if (ptr == NULL){
        throw Exception("访问不存在的单位类型");
    }
    return ptr->lifeLimit;
}

double BaseUnit::getDefend()const{
    const ArmyInfo *ptr = getArmy(index);
    if (ptr == NULL){
        throw Exception("访问不存在的单位类型");
    }
    return ptr->defend;
}

double BaseUnit::getConsumeTime()const{
    const ArmyInfo *ptr = getArmy(index);
    if (ptr == NULL){
        throw Exception("访问不存在的单位类型");
    }
    return ptr->consumeTime;
}

double BaseUnit::getConsumeMoney()const{
    const ArmyInfo *ptr = getArmy(index);
    if (ptr == NULL){
        throw Exception("访问不存在的单位类型");
    }
    return ptr->consumeMoney;
}

double BaseUnit::getConsumeEnergy()const{
    const ArmyInfo *ptr = getArmy(index);
    if (ptr == NULL){
        throw Exception("访问不存在的单位类型");
    }
    return ptr->consumeEnergy;
}

bool BaseUnit::isDie()const{ return life < 0; }

const string &BaseUnit::getName()const{
    const ArmyInfo *ptr = getArmy(index);
    if (ptr == NULL){
        throw Exception("访问不存在的单位类型");
    }
    return ptr->name;
}

uint64_t BaseUnit::getId()const{ return id; }

uint32_t BaseUnit::getTeam()const{ return team; }

const Location &BaseUnit::getLocation()const{ return loc; }

double BaseUnit::getFinishPercent()const{
    const ArmyInfo *ptr = getArmy(index);
    double tmp = (time(NULL) - buildTime) / getConsumeTime();
    return (tmp >= 1)? 1 : tmp;
}

bool BaseUnit::consumeLife(double consume){
    if (isDie()){
#if USE_LOG
        cerr << "**************************************************" << endl;
        cerr << "对一个已经死亡的单位扣血" << endl;
        cerr << "单位地址:" << (void *)this << endl;
        cerr << "单位名称:" << getName() << endl;
        cerr << "单位id:" << getId() << endl;
        cerr << "**************************************************" << endl;
#endif
        return false;
    }
    life -= consume;
    destroy();
    return true;
}

bool BaseUnit::addLife(double add){
    if (isDie()){
#if USE_LOG
        cerr << "**************************************************" << endl;
        cerr << "对一个已经死亡的单位加血" << endl;
        cerr << "单位地址:" << (void *)this << endl;
        cerr << "单位名称:" << getName() << endl;
        cerr << "单位id:" << getId() << endl;
        cerr << "**************************************************" << endl;
#endif
        return false;
    }
    life = (life + add < getArmy(index)->lifeLimit)? life + add : getArmy(index)->lifeLimit;
    return true;
}

void BaseUnit::build(){
    buildTime = NowTime();
    life = getArmy(index)->lifeLimit;
}

